package com.dao;


import com.utils.JDBCUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * @author zxl
 * @create :2022/9/28
 */
/*
* BaseDao是所有针对数据库操作的基本类
* 需要在里面设置一些通用的方法来解决增删改查代码重复的问题
*
*
* */
public abstract class BaseDao {
    //所有的操作都需要用到QueryRunner 定义为全局属性 值为对象
    private QueryRunner queryRunner = new QueryRunner();
    Connection conn= null;

    /**
     * 该方法是进行增 删 改的通用的方法
     * @param sql  传入你要操作的sql
     * @param args  传入你要使用的参数  ？
     * @return  执行后受影响的行数
     */
    public  int update(String sql,Object ... args){

        try {
            //打开连接
            conn= JDBCUtils.getConn();
            return queryRunner.update(conn, sql, args);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //将连接放回连接池
            JDBCUtils.closeConn2(conn);
        }

        return -1;//出错
    }


    /**
     * 根据传入的sql查询单个对象的方法
     * @param clazz 最终查询后要返回的对象.class
     * @param sql  不同的查询单个对象的sql
     * @param args sql语句的问号的参数
     * @param <T>  根据clazz得到一个最用的泛型  将这个泛型作为对象返回
     * @return 查询到的对象
     */
    public <T>T selectForOne(Class<T> clazz,String sql,Object ... args){
        try {
            conn=JDBCUtils.getConn();
            System.out.println(conn);
            return queryRunner.query(conn, sql, new BeanHandler<>(clazz), args);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.closeConn2(conn);
        }

        return null;//失败
    }

    /**
     * 通用的查询多个对象的方法
     * @param clazz 要查询的对象类型
     * @param sql  传入的sql语句
     * @param args 参数
     * @param <T>  要查询的类.class  类型
     * @return 查询到的集合
     */
    public  <T> List<T> selectForList(Class<T> clazz, String sql, Object ... args){
        try {
            conn=JDBCUtils.getConn();
            return queryRunner.query(conn,sql,new BeanListHandler<>(clazz),args);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.closeConn2(conn);
        }
        return null;
    }


    /**
     * 通用的查询单个值的方法  max
     * @param sql 传入的sql
     * @param args  参数
     * @return  返回查询到的值
     */
    public Object selectForValue(String sql,Object ... args){
        try {
            conn=JDBCUtils.getConn();
            return queryRunner.query(conn,sql,new ScalarHandler(),args);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.closeConn2(conn);
        }
        return null;
    }



}
